angular.module("ui.ssnau.dnd", [])
    .directive("uiDnd", function() {

        var isDragging = false,
            info = null,
            cssOver = "dragging-over";

        function clear() {
            isDragging = false;
            info = null;
        }

        return function(scope, elem, attrs) {
            var config = scope.$eval(attrs['uiDnd']),
                dragFun = resolveFunc(config.drag || angular.noop),
                dropFun = resolveFunc(config.drop || angular.noop),
                allowDropFun = resolveFunc(config.allowDrop || angular.noop);

            function resolveFunc(f) {
                return angular.isString(f) ? function(){
                    return scope.$eval(f);
                } : f;
            }

            //如果允许drag
            if (config.drag) {
                elem.attr("draggable", true);
                elem.on('dragstart', function(){
                    clear();
                    info = dragFun();
                    isDragging = true;
                });
            }

            //如果允许drop
            if (config.drop) {
                //如果有allowDrop的属性，则通过查看allowDrop是否反正true来判断
                //是否allow drop
                elem.on('dragover', function(e) {
                    if (config.allowDrop) {
                        /**
                         * info即为dragstart时设进去的东西
                         * scope即为当前elem所在的scope,用以辅助AllowDropFunc做判断
                         * e：如果scope还不够用的话，就上e
                         */
                        if(allowDropFun(info, scope, e)) {
                            e.preventDefault();
                            elem.addClass(cssOver);
                        }
                    } else {
                        e.preventDefault();
                        elem.addClass(cssOver);
                    }
                });
                elem.on('dragleave', function(e) {
                    elem.removeClass(cssOver);
                });
                elem.on("drop", function(e){
                   if (isDragging && info) {
                       dropFun(info, scope, e);
                   }
                    clear();
                    elem.removeClass(cssOver);
                });
            }
        }
    });